package com.zwh.common.codec;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author zwh
 * @date 2022-6-2
 */
public class CryptJSTest {


    /**
     *
     * @param password
     * @param keySize
     *            单位 比特
     * @param ivSize
     *            单位 比特
     * @param salt 盐
     * @param resultKey 生成的key
     * @param resultIv 生成的iv
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey,
                                byte[] resultIv) throws NoSuchAlgorithmException {
        return EvpKDF(password, keySize, ivSize, salt, 1, "MD5", resultKey, resultIv);
    }

    /**
     *
     * @param password
     * @param keySize
     *            单位 比特
     * @param ivSize
     *            单位 比特
     * @param salt
     *            盐
     * @param iterations
     *            循环次数
     * @param hashAlgorithm
     *            摘要算法, 默认使用md5散列
     * @param resultKey
     * @param resultIv
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int iterations,
                                String hashAlgorithm, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
        keySize = keySize / 32;
        ivSize = ivSize / 32;
        int targetKeySize = keySize + ivSize;// =8+4=12块
        byte[] derivedBytes = new byte[targetKeySize * 4];// 所需字节
        int numberOfDerivedWords = 0;// 4字节计数
        byte[] block = null;
        MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);
        while (numberOfDerivedWords < targetKeySize) {
            if (block != null) {
                hasher.update(block);
            }
            hasher.update(password);
            hasher.update(salt);
            block = hasher.digest();

            hasher.reset();

            // Iterations
            for (int i = 1; i < iterations; i++) {
                block = hasher.digest(block);
                hasher.reset();
            }

            System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords * 4,
                    Math.min(block.length, (targetKeySize - numberOfDerivedWords) * 4));

            numberOfDerivedWords += block.length / 4;
        }

        System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4);
        System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4);

        return derivedBytes; // key + iv
    }


    public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        byte[] passwordBuff = "AAEE123".getBytes("utf-8");
        byte[] saltBuff = new byte[8];

        byte[] keyBuff = new byte[32];
        byte[] ivBuff = new byte[16];
        EvpKDF(passwordBuff, 256, 128, saltBuff, keyBuff, ivBuff);
    }
}
